#include "YieldCurve.hpp"

using namespace provident;

YieldCurve::YieldCurve(Type const type)
:   _type(type), _flatYield(0.0), _termYields(1), _termYearsTilDate(1)
{
}

YieldCurve::YieldCurve(const double flatYield)
:   _type(FLAT_YIELD), _flatYield(flatYield), _termYields(1), _termYearsTilDate(1)
{
}
YieldCurve::YieldCurve(const Term terms[], const double yields[])
:   _type(INTERPOLATED_YIELD), _flatYield(0.0), _termYields(1), _termYearsTilDate(1)
{
}
YieldCurve::YieldCurve(const double discretizedDates[], const double yields[])
:   _type(DISCRETIZED_YIELD), _flatYield(0.0), _termYields(1), _termYearsTilDate(1)
{
}

YieldCurve::YieldCurve(Type const type, const double discretizedDates[], const double yields[])
:   _type(type), _flatYield(0.0), _termYields(1), _termYearsTilDate(1)
{
}

const YieldCurve::Term YieldCurve::getNearestTermBefore(const double yearsTilDate)
{
    return OVERNIGHT;
}
const YieldCurve::Term YieldCurve::getNearestTermAfter(const double yearsTilDate)
{
    return OVERNIGHT;
}

const double YieldCurve::getNearestYieldBefore(const double yearsTilDate)
{
    return 0.0;
}
const double YieldCurve::getNearestYieldAfter(const double yearsTilDate)
{
    return 0.0;
}


void YieldCurve::setYield(const double flatYield)
{
    _flatYield = flatYield;
}

void YieldCurve::setYield(const Term term, const double yield)
{
    _termYields[term] = yield;
}

void YieldCurve::setYield(const double discretizedDate, const double yield)
{
}


double YieldCurve::yieldForDate(const double yearsTilDate)
{
    if (_type == FLAT_YIELD)
        return _flatYield; 
    if (_type == DISCRETIZED_YIELD)
        return 0.0;

    // Linear approximation between closest two terms
    Term before = getNearestTermBefore(yearsTilDate);
    Term after = getNearestTermAfter(yearsTilDate);

    double slope = (_termYields[after] - _termYields[before]) 
                   / (_termYearsTilDate[after] - _termYearsTilDate[before]);

    return slope * (yearsTilDate - _termYearsTilDate[before]) + _termYields[before];
}

